package gougeon.java.solveurdictionnaire;




import java.util.ArrayList;
import java.util.HashMap;

//import android.os.Handler;
//import android.os.Message;
//import android.util.Log;

/**
 * @author lgougeon
 *
 */
public class chaine {
    
  long   chaine_id;
  String the_chaine;
  int    num_magic_char=0;
  String charset="ABCDEFGHIJKLMNOPQRSTUVWXYZÉÈÊËÀÂÎÏÛÇÔÙÜ";
  int    char_ids[]={   2,   3,   5,   7,  11,  13,  17,  19,
		               23,  29,  31,  37,  41,  43,  47,  53,
		               59,  61,  67,  71,  73,  79,  83,  89, 
		               97, 101,  11,  11,  11,  11,   2,   2,
		               23,  23,  73,   5,  47,  73,  73};
  int progress=1;
  
  public chaine(String input_string)
  {
	int idx,char_id;
	char my_char;
	the_chaine=input_string;
	chaine_id=1;

	for (idx=0; idx<the_chaine.length(); idx++)
	{
	  my_char=the_chaine.charAt(idx);
	  if (my_char==' ')
	  {
		String loc_chaine="";
		if (idx==0)
		  loc_chaine=the_chaine.substring(1, the_chaine.length());
		else if (idx==the_chaine.length()-1)
	      loc_chaine=the_chaine.substring(0,the_chaine.length()-1);
		else
	      loc_chaine=the_chaine.substring(0, idx)+the_chaine.substring(idx+1,the_chaine.length());

		the_chaine=loc_chaine;
		num_magic_char++;
	  }
	}
	for (idx=0; idx<the_chaine.length(); idx++)
	{
	  my_char=the_chaine.charAt(idx);
	  if (charset.indexOf(my_char)!=-1)
	  {
	    char_id=char_ids[charset.indexOf(my_char)];
	    chaine_id=chaine_id*char_id;
	  }
	  else
	  {
		  chaine_id=0;
		 // Log.e("solveur", "New chaine : invalid ! (\""+this.the_chaine+"\")");
	  }
	}
  	//System.out.println("New chaine : \""+this.the_chaine+"\" (ART l="+the_chaine.length()+") ("+chaine_id+") num_magic_char="+num_magic_char);
  }

  public String toString()
  {
	return this.the_chaine;
  }
  
  public int length()
  {
	return this.the_chaine.length();
  }

	public int analyse(	HashMap<String, ArrayList<String>> mots_de_2_lettres,
						HashMap<String, ArrayList<String>> mots_de_3_lettres,
						HashMap<String, ArrayList<String>> mots_de_4_lettres,
						HashMap<String, ArrayList<String>> mots_de_5_lettres,
						HashMap<String, ArrayList<String>> mots_de_6_lettres,
						HashMap<String, ArrayList<String>> mots_de_7_lettres,
						HashMap<String, ArrayList<String>> mots_de_8_lettres,
						HashMap<String,String> liste_de_mots_trouves,
						int current_key[],
		//				Handler handler,
						int min_size,
						int max_size)
	{
		int idx/*,jdx,pow=1*/;
		//double zow=pow(double(26),);
	//	Message msg3 = new Message();
	//	for (jdx=0;jdx<num_magic_char;jdx++)
	//	{
	//		pow=pow*26;
	//	}
//		msg3.arg1=26*pow*(the_chaine.length()+num_magic_char);
//		msg3.what=6;
//		handler.sendMessage(msg3);

		// Consider every possible char added to input (existing char on the board)
		for (idx=0;idx<26; idx++)
		{
			chaine magic_chaine=new chaine (charset.charAt(idx)+the_chaine);
			magic_chaine.analyse(	num_magic_char,
									num_magic_char,
									charset.charAt(idx),
									mots_de_2_lettres,
									mots_de_3_lettres,
									mots_de_4_lettres,
									mots_de_5_lettres,
									mots_de_6_lettres,
									mots_de_7_lettres,
									mots_de_8_lettres,
									liste_de_mots_trouves,
									current_key,
		//							handler,
									min_size,
									max_size);
		}
		return 0;
	}

	public int analyse(int loc_num_magic_char,
						int total_magic_char,
						char value_of_existing_char,
						HashMap<String, ArrayList<String>> mots_de_2_lettres,
						HashMap<String, ArrayList<String>> mots_de_3_lettres,
						HashMap<String, ArrayList<String>> mots_de_4_lettres,
						HashMap<String, ArrayList<String>> mots_de_5_lettres,
						HashMap<String, ArrayList<String>> mots_de_6_lettres,
						HashMap<String, ArrayList<String>> mots_de_7_lettres,
						HashMap<String, ArrayList<String>> mots_de_8_lettres,
						HashMap<String,String> liste_de_mots_trouves,
						int current_key[],
		//				Handler handler,
						int min_size,
						int max_size)
	{
		int idx;
		//Log.d("solveur", "analyse("+loc_num_magic_char+")");

		if (loc_num_magic_char==0)
		{
			//for (idx=this.the_chaine.length();idx>1; idx--)
			for (idx=max_size;idx>=min_size; idx--)
			{
				/*Message msg = new Message();
				msg.arg1=progress++;
				msg.what=5;*/
	//			handler.sendEmptyMessage(5);

				combination("",this.the_chaine, idx,
							total_magic_char,
							value_of_existing_char,
							mots_de_2_lettres,
							mots_de_3_lettres,
							mots_de_4_lettres,
							mots_de_5_lettres,
							mots_de_6_lettres,
							mots_de_7_lettres,
							mots_de_8_lettres,
							liste_de_mots_trouves,
							current_key);
			}
		}
		else
		{
			for (idx=0;idx<26; idx++)
			{
				chaine magic_chaine=new chaine (charset.charAt(idx)+the_chaine);
				magic_chaine.analyse(	loc_num_magic_char-1,
										total_magic_char,
										value_of_existing_char,
										mots_de_2_lettres,
										mots_de_3_lettres,
										mots_de_4_lettres,
										mots_de_5_lettres,
										mots_de_6_lettres,
										mots_de_7_lettres,
										mots_de_8_lettres,
										liste_de_mots_trouves,
										current_key,
		//								handler,
										min_size,
										max_size);
			}
		}
		return 0;
	}


  public static void combination(String head, String tail, int k,
		    int total_magic_char,
	        char value_of_existing_char,
		    HashMap<String, ArrayList<String>> mots_de_2_lettres,
            HashMap<String, ArrayList<String>> mots_de_3_lettres,
		    HashMap<String, ArrayList<String>> mots_de_4_lettres,
            HashMap<String, ArrayList<String>> mots_de_5_lettres,
		    HashMap<String, ArrayList<String>> mots_de_6_lettres,
            HashMap<String, ArrayList<String>> mots_de_7_lettres,
            HashMap<String, ArrayList<String>> mots_de_8_lettres,
            HashMap<String,String> liste_de_mots_trouves,
            int current_key[])
  {
    if (tail.length()<k)  // we are unable to pick k letters from tail
    {
      return;  // no combination at all
    }
    else if (k==0)  // combination found
    {
    	HashMap<String, ArrayList<String>> current_hash=null;
    	chaine sub_chaine= new chaine(head);
    	
    	switch(sub_chaine.length())
    	{
    	  case 2: current_hash=mots_de_2_lettres; break;
    	  case 3: current_hash=mots_de_3_lettres; break;
    	  case 4: current_hash=mots_de_4_lettres; break;
    	  case 5: current_hash=mots_de_5_lettres; break;
    	  case 6: current_hash=mots_de_6_lettres; break;
    	  case 7: current_hash=mots_de_7_lettres; break;
    	  case 8: current_hash=mots_de_8_lettres; break;
    	  default : break;
    	}
    	if (current_hash!=null)
    	{
    	  sub_chaine.check_dico(current_hash,liste_de_mots_trouves,current_key,total_magic_char,value_of_existing_char);
    	}
    }
    else
    {
      String new_tail = tail.substring(1);
      String new_head = head+tail.charAt(0);
      combination(new_head,new_tail, k-1,
    		      total_magic_char,
		          value_of_existing_char,
    		      mots_de_2_lettres,
    		      mots_de_3_lettres,
		          mots_de_4_lettres,
		          mots_de_5_lettres,
		          mots_de_6_lettres,
		          mots_de_7_lettres,
		          mots_de_8_lettres,
		          liste_de_mots_trouves,
    		      current_key);
      combination(head, new_tail, k,
		          total_magic_char,
	              value_of_existing_char,
		          mots_de_2_lettres,
		          mots_de_3_lettres,
		          mots_de_4_lettres,
		          mots_de_5_lettres,
		          mots_de_6_lettres,
		          mots_de_7_lettres,
		          mots_de_8_lettres,
		          liste_de_mots_trouves,
		          current_key);
    }
  }

  int check_dico(HashMap<String, ArrayList<String>> current_hash,
		  HashMap<String,String> liste_de_mots_trouves,
		  int current_key[],
		  int total_magic_char,
		  char value_of_existing_char)
  {
	  int idx;
	  //Log.d("solveur", "check_dico : "+this.the_chaine);
	  if (current_hash.containsKey(String.valueOf(chaine_id)))
	  {
		// Found a match !
		// Look into the found words if this word already exist.
		for (idx=0; idx<current_hash.get(String.valueOf(chaine_id)).size(); idx++)
		{
		  if (liste_de_mots_trouves.containsValue(current_hash.get(String.valueOf(chaine_id)).get(idx)))
		  {
			// First word of this key exist, don't add it again.
			
		  }
		  else
		  {
			liste_de_mots_trouves.put(String.valueOf(current_key[0]++), current_hash.get(String.valueOf(chaine_id)).get(idx));
			  
		/*	if (current_hash.get(String.valueOf(chaine_id)).get(0).indexOf(value_of_existing_char)==-1)
			  Log.d("solveur","Found match to "+current_hash.get(String.valueOf(chaine_id)).get(idx)+" with "+total_magic_char+" blank chars");
			else	
			  Log.d("solveur","Found match to "+current_hash.get(String.valueOf(chaine_id)).get(idx)+" with "+total_magic_char+" blank chars and \""+value_of_existing_char+"\" on the board");
			//Log.d("solveur","current_key="+current_key[0]+" Liste=("+liste_de_mots_trouves+")");
		 */ }
		}		
	  }
	  return 3;
  }
}
